package br3akr.DeadlyDinnerParty.Server.Actions;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

import br3akr.DeadlyDinnerParty.Server.Engine.Session;
import br3akr.DeadlyDinnerParty.Server.Exceptions.DeadlyDinnerPartyException;
import br3akr.DeadlyDinnerParty.Server.World.Area;
import br3akr.DeadlyDinnerParty.Server.World.Chest;
import br3akr.DeadlyDinnerParty.Server.World.GameCharacter;
import br3akr.DeadlyDinnerParty.Server.World.Item;

public class GetAction extends Action {
	boolean actionComplete;
    private ActionResponse actionResponse;
    public static final Set<String> keywords;
	static
	{
		Set<String>tempKeywords = new HashSet<String>();
		tempKeywords.add("Get");
		keywords = Collections.unmodifiableSet(tempKeywords);
	}
    
    public GetAction() {
        super("Get", false);
    }
    
    public ActionResponse doAction(String action, Session session) throws DeadlyDinnerPartyException {
		if (action == null) {
			throw new DeadlyDinnerPartyException ("No action found.");
		}
		if (session == null) {
			throw new DeadlyDinnerPartyException ("No session found.");
		}
		
    	StringTokenizer tokenizedAction = new StringTokenizer(action);
    	String keyword = tokenizedAction.nextToken();
    	String param1 = tokenizedAction.nextToken();
    	
		GameCharacter actor = session.getCharacter();
		
		if (actor == null) {
			throw new DeadlyDinnerPartyException ("No character found for your session.");
		}
    	
    	actionResponse = new ActionResponse();
    	actionResponse.setActingCharacter(session.getCharacter());
    	Area location = session.getCharacter().getLocation();
    	Chest chest = null;
    	
    	Set<GameCharacter> localOnlookers = location.getAreaOnlookers(session.getCharacter(), null);
    	actionResponse.addAffectedArea(location);
    	Item it = null;
    	
    	if (param1 == null) {
    		throw new DeadlyDinnerPartyException("Get what?");
    	}
    	
    	chest = location.getChest(param1);
    	String itemName = null;
    	StringBuilder actorDesc = new StringBuilder();
    	StringBuilder onlookDesc = new StringBuilder();
    	
    	if (chest != null) {
        	if (chest.isLocked()) {
        		throw new DeadlyDinnerPartyException(chest.getName() + " is locked.");
        	}
        	itemName = action.substring(action.indexOf(param1) + param1.length()).trim();
        	it = chest.getItem(itemName);
        	
        	if (it == null) {
        		throw new DeadlyDinnerPartyException("There is no item in " + chest.getName() + " called " + itemName + ".");
        	}
        	
        	chest.removeItem(it);
        	
        	if (actor.getHeldItem() != null) {
        		actorDesc.append("You place your " + actor.getHeldItem().getName() + " in your inventory.  ");
        		onlookDesc.append(actor.getName() + " places their " + actor.getHeldItem().getName() + " in their inventory.  ");
        		actor.addItem(actor.getHeldItem());
        	}
        	
        	actor.holdItem(it);
    		actionResponse.addOnlookers(localOnlookers, onlookDesc.toString() + actor.getName() + " gets something out of " + chest.getName() + ".");
    		actionResponse.setActingCharacterDescription(actorDesc.toString() + "You get " + it.getName() + " out of " + chest.getName() + ".");
    		beginRecovery(session.getCharacter(), 3000);
    	} else {
    		itemName = action.substring(action.indexOf(keyword) + keyword.length()).trim();
    		it = actor.getInventoryItem(itemName);
    		
    		if (it != null) {
            	if (actor.getHeldItem() != null) {
            		actorDesc.append("You place your " + actor.getHeldItem().getName() + " in your inventory.  ");
            		onlookDesc.append(actor.getName() + " places their " + actor.getHeldItem().getName() + " in their inventory.  ");
            		actor.addItem(actor.getHeldItem());
            	}
    			actor.removeItem(it);
    			actor.holdItem(it);
        		actionResponse.addOnlookers(localOnlookers, onlookDesc.toString() + actor.getName() + " pulls " + it.getName() + " out of his inventory.");
        		actionResponse.setActingCharacterDescription(actorDesc.toString() + "You get " + it.getName() + " out of your inventory.");
    		} else {
    			it = location.getItem(itemName);
    			
    			if (it == null || it.isHiddenFrom(actor)) {
    				throw new DeadlyDinnerPartyException ("There is no item here called " + itemName);
    			}
    			
            	if (actor.getHeldItem() != null) {
            		actorDesc.append("You place your " + actor.getHeldItem().getName() + " in your inventory.  ");
            		onlookDesc.append(actor.getName() + " places their " + actor.getHeldItem().getName() + " in their inventory.  ");
            		actor.addItem(actor.getHeldItem());
            	}
    			location.removeItem(it);
    			actor.holdItem(it);
        		actionResponse.addOnlookers(localOnlookers, onlookDesc.toString() + actor.getName() + " picks up " + it.getName() + ".");
        		actionResponse.setActingCharacterDescription(actorDesc.toString() + "You pick up " + it.getName() + ".");
    		}
    	}

    	actionComplete = true;
        return actionResponse;
    }
	
    public ActionResponse getActionResponse() {
		return actionResponse;
	}
    
    public Set<String> getKeywords() {
        return keywords;
    }
}